package controllers;
import java.awt.event.ActionEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Observer;

import javax.swing.JOptionPane;

import model.BuyPhotoOrSampleModel;
import model.CustomerPhotosModel;
import model.SearchPhotoModel;
import model.SearchResultModel;
import model.PermissionModel;
import model.UserPermissions;
import model.ViewPhotoModel;
import client.CliMessage;
import view.BuyPhotoOrSampleGUI;
import view.SearchResultGUI;
import view.ViewPhotoGUI;
import view.ViewPhotoSampleGUI;


/**
 * The Class SearchResultController. extends AbstractController
 * @author Tomer & Tal
 */
public class SearchResultController extends AbstractController
{
	
	/** The search res view. */
	private SearchResultGUI searchResView;
	
	/** The search res model. */
	private SearchResultModel searchResModel;
	
	/** The up. */
	private UserPermissions up;
	
	/** The user account balance. */
	private int balance; 
	
	/** The pressed Photo button index. */
	private int pressedPhotoButtonIndex;
	
	/** The pressed Sample button index. */
	private int pressedSampleButtonIndex;
	
	/** The photo to display details. */
	private  SearchPhotoModel photoDetails;
	
	/**  The action listeners for the buttons. */
	private HashMap <String,AbstractListener> listeners;
	
	/** flag if pressed buy sample. */
	private boolean ViewSampleFlag=false;
	
	/** flag if sample before discount  on Photo. */
	private boolean discount=false;
	
	/** The change. */
	private boolean change=false;
	
    /** The watch photos. */
    private ArrayList<CustomerPhotosModel> watchPhotos;
    
    /** The user per. */
    private ArrayList<PermissionModel> userPer;
	   
	/**
	 * Instantiates a new search result controller.
	 */
	public SearchResultController() 
	{
		super(null, null);
	
	}
	
	/**
	 * Instantiates a new search result controller.
	 *
	 * @param searchResModel the search res model
	 */
	public SearchResultController(SearchResultModel searchResModel) 
	{
		super(null, searchResModel);
		this.searchResModel = searchResModel;
	}
	
	/**
	 * Instantiates a new search result controller.
	 *
	 * @param searchResView the search res view
	 * @param searchResModel the search res model
	 */
	public SearchResultController(SearchResultGUI searchResView , SearchResultModel searchResModel) 
	{
		super(searchResView, searchResModel);
		this.searchResView = searchResView;
		this.searchResModel = searchResModel;
		this.up = UserPermissions.getInstance(0, null,null);
		setActionListeners();
	}
	
	 /**
 	 * Sets the watch photos.
 	 *
 	 * @param pics the new watch photos
 	 */
 	public void setWatchPhotos(ArrayList<CustomerPhotosModel> pics)
	  {
	    	watchPhotos=new ArrayList<CustomerPhotosModel>();
	    	
	    	for(int i=0;i<pics.size();i++)
	    	{
	    		watchPhotos.add(new CustomerPhotosModel(pics.get(i).getUID(),pics.get(i).getPhoto()));
	    	}
	   }
	 
	 /**
 	 * Sets the user permissions.
 	 *
 	 * @param user the new user permissions
 	 */
 	public void setUserPermissions(ArrayList<PermissionModel> user)
	  {
		 userPer=new ArrayList<PermissionModel>();
	    	
	    	for(int i=0;i<user.size();i++)
	    	{
	    		userPer.add(new PermissionModel(user.get(i).getUID(),user.get(i).getGroupID(),user.get(i).getGroupName()));
	    	}
	   }
	 
	/**
	 * Checks for packege.
	 *
	 * @param user the user
	 * @return true, if successful
	 */
	public boolean hasPackege(ArrayList<PermissionModel> user)
	{
		for(int i=0;i<userPer.size();i++)
		{
		  for(int j=0;j<user.size();j++)	
		  {
		   if(user.get(j).getGroupName().equals("Package Customer") && userPer.get(i).getUID()==user.get(j).getUID())
		    {
			 System.out.println("Has Package");
			   return true;
		    }
		  }
		}
		
		System.out.println("Doesnt has Package");
		return false;
	}

	/**
	 * Watch photo.
	 *
	 * @param watch the watch
	 * @return true, if successful
	 */
	public boolean watchPhoto(CustomerPhotosModel watch)
	{
		for(int i=0;i<watchPhotos.size();i++)
		{
			if(watchPhotos.get(i).getUID()==watch.getUID() && watchPhotos.get(i).getPhoto().getLocation()==watch.getPhoto().getLocation() && watchPhotos.get(i).getPhoto().getTimeStamp().equals(watch.getPhoto().getTimeStamp()))
			{	
		     //	System.out.println(watchPhotos.get(i).getUID()+"::::");
		        System.out.println("Already Watch photo");
		        
		       return true;
			}
		}
		
		
		System.out.println("Doesnt Watch photo");
		return false;
	}
	
	/**
	 * checks date validation.
	 *
	 * @param myYear the my year
	 * @param myMonth the my month
	 * @return the validate date
	 */
	public boolean getDateValidation(int myYear,int myMonth)
	{
	
		//CurrentDate
		Date date = new Date();
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		
		String currTime= sd.format(date);
		
	    Date currentDate=null;
		try {
			currentDate = sd.parse(currTime);
		} catch (ParseException e) {
			System.out.println("Current Date parse Problem");
			e.printStackTrace();
		}
		
		int currYear=Integer.parseInt(currTime.substring(0, 4));
		int currMonth=Integer.parseInt(currTime.substring(5, 7));
		 System.out.println("Curr Date:"+":"+currYear+":"+currMonth);
		 //check 
		 if (currMonth<myMonth)
			  return false;
		 
		 if (currYear<myYear)
             return false;
		 return true;
	}
	
	/**
	 * open Buy photo or Sample
	 * create new objects GUI,Model,Controller.
	 *
	 * @param flag the flag
	 */
	
   public void callBuyPhoto(boolean flag)
   {
	   int serviceId;
		//create a new buy photo controller
		BuyPhotoOrSampleGUI buyPhotoView = new BuyPhotoOrSampleGUI();
		BuyPhotoOrSampleModel buyreqModel = new BuyPhotoOrSampleModel();
		
		//init buy request 
		buyreqModel.setUID(up.getCurrUserID());

		int btn;
		
		 if (ViewSampleFlag)
		 {
			 System.out.println("Sample----go to buy");
			 serviceId=3;
			 ViewSampleFlag=false;
			 btn=pressedSampleButtonIndex;
		 }
		 else
		 {
			 serviceId=1;
			 btn=pressedPhotoButtonIndex;
		 }
		 
		System.out.println("uid:"+up.getCurrUserID());
		
		photoDetails = searchResModel.getPhotoHeadlineList().get(btn);
		
	
		
		BuyPhotoController buyPhotoCon = new BuyPhotoController(buyPhotoView,buyreqModel,photoDetails,this,searchResView,serviceId,flag);
				
		//add observer to new controller and delete the rest
		setCurrentObserver(buyPhotoCon);						
		
		//add a listener to "back" button in buy sub  window
		setBackListener(this,buyPhotoView);
   }
   
   /**
    * open View Photo according to user choice
    * create new Objects GUI,Model,Controller.
    */
   
   public void ViewPhoto()
   {
	    photoDetails = searchResModel.getPhotoHeadlineList().get(pressedPhotoButtonIndex);
	   
        //set the view photo model with a photo to display
		ArrayList<SearchPhotoModel> photosToDispley = new ArrayList<SearchPhotoModel>(); //set the photo list
		photosToDispley.add(photoDetails); //add a photo to list 
		SearchResultModel photos = new SearchResultModel(photosToDispley);
		ViewPhotoModel photoModel = new ViewPhotoModel(photos);
		
		//print the link to file (in console - for developer)
		String photoToDisplayFilePath = photoDetails.getLinkToFile();
		System.out.println("View Photo:"+photoToDisplayFilePath);
		
		//set the GUI and Controller of view photo
		ViewPhotoGUI photoView = new ViewPhotoGUI();
		
		ViewPhotoController viewPhotoCon = new ViewPhotoController(photoView,photoModel);
		
		//add observer to new controller and delete the rest
		setCurrentObserver(viewPhotoCon);						
		
		//add a listener to "back" button in View Photo  window
		setBackListener(this,photoView);
   }
   
   /**
    * open View Photo Sample according to user choice
    * create new Objects GUI,Model,Controller.
    */
   
   public void ViewPhotoSample()
   {
	    photoDetails = searchResModel.getPhotoHeadlineList().get(pressedSampleButtonIndex);
	 
		//print the link to file (in console - for developer)
		String photoToDisplayFilePath = photoDetails.getLinkToFile();
		System.out.println("View Photo Sample:"+photoToDisplayFilePath);
		
		//set the GUI and Controller of view photo
		ViewPhotoSampleGUI photoSampleView = new ViewPhotoSampleGUI();
		
		ViewPhotoSampleController viewPhotoSampleCon = new ViewPhotoSampleController(photoSampleView,photoDetails);
		
		//add observer to new controller and delete the rest
		setCurrentObserver(viewPhotoSampleCon);						
		
		//add a listener to "back" button in View Photo Sample  window
		setBackListener(this,photoSampleView);
   }
	
	/* (non-Javadoc)
	 * @see client.IObserve#handleDBRequestSuccess()
	 */
	@Override
	public void handleDBRequestSuccess() 
	{
		
	}

	
	/* (non-Javadoc)
	 * @see client.IObserve#handleNullSearchResult()
	 */
	@Override
	public void handleNullSearchResult() {
		///chcek if view photo
		if(change==false)
		{
			System.out.println("enter chaking");
			//check if sample exist 
				 int uid=up.getCurrUserID();
			    photoDetails = searchResModel.getPhotoHeadlineList().get(pressedPhotoButtonIndex);
					
					int location=photoDetails.getLocation();
					String timestamp=photoDetails.getTimeStamp();	 
					System.out.println(location+""+timestamp);
		  	///send query watch Sample before and left 
					String sql = "search"   + "SELECT *"
					                      + " FROM customer_samples AS p"
					                      + " WHERE p.uid="+ uid +" AND p.locationsample="+location+" AND p.timestampsample='"+ timestamp + "'";
					                    
							 
					// Send a query to DB
					sendToServer(sql);
		  change=true;		
		  discount=true;
			
		}
	else//only if null after	
	{
		     callBuyPhoto(false);
		     change=false;
	}

}

	
	 
	/* (non-Javadoc)
	 * @see client.IObserve#handleDBSearchResult(client.CliMessage)
	 */
	@Override
	public void handleDBSearchResult(CliMessage dbResult) 
	{
		boolean flag=true;
		boolean photoOrSample=true;
		ArrayList<HashMap<String,String>> res = ((CliMessage)dbResult).getSrs();
		int Size=res.size();
		  
			
		//watch & got Account
		if (Size==2)
		{	
			System.out.println("both");
			//View Photo
			ViewPhoto();
		}
	
		//watch photo or got account
		if (Size==1)
		{
			System.out.println("or::::::::::::::");
			
			
			
			
			int btn;
			 if (ViewSampleFlag)	//sample pressed
				 btn= pressedSampleButtonIndex;
			 else
				 btn=pressedPhotoButtonIndex;
			 
			photoDetails = searchResModel.getPhotoHeadlineList().get(btn);
			
			String photoLocation=res.get(0).get("LOC");
			String photoTimeStamp=res.get(0).get("time");
			String sampleLoc=res.get(0).get("LOCATIONSAMPLE");
			System.out.println("location photo"+photoLocation);
			System.out.println("location sample"+ sampleLoc);
			
			if(sampleLoc!=null)
			{
				
				photoOrSample=false;
			}
			else
			if (!photoLocation.equals("") )
			{
				photoOrSample=false;
				
			}
			else
				  photoOrSample=true;
			
			
		//got account and not watch photo
		if (photoOrSample)
		{
			System.out.println("got Account::::::::::::::");
			   balance=Integer.parseInt(res.get(0).get("BALANCE"));
			   String accTimeStamp =res.get(0).get("TIMESTAMP");	
		
			 int year=Integer.parseInt(accTimeStamp.substring(0, 4));
			 int month=Integer.parseInt(accTimeStamp.substring(5, 7));
			 
			
			if (balance==0)
			   flag=false;
			
			if(!getDateValidation(year,month))
				flag=false;
			
			System.out.println("flag"+flag);
			 int uid=up.getCurrUserID();
			// System.out.println("From DB:"+":"+year+":"+month);
			 System.out.println("Balance:::::"+balance);
			 
			 //account expire
			if (flag==false)
			{ 
				String msg;
				
				///joptionPane go subscribed again
				
				if (balance==0)
				  msg="Your Account is Reached is Limit ,Going To Buy....  ";
				else
				  msg="Your Account is Expired ,Going To Buy....";
							
				
				  JOptionPane.showMessageDialog(null, msg, "Account Problem", JOptionPane.ERROR_MESSAGE);
				
				//Update acount to disActivated	  
					String delsql1 = "adu" + "UPDATE customer_account " 
							               + " SET active = 0" 
		                                   + " WHERE uid = " + uid + "" 
		                                   + " AND subscription_type = 2 ";
		                    
				 
		         // Send a query to DB
		          sendToServer(delsql1);
				  //delete from user_groups
		          String delsql2 = "adu" + "DELETE FROM user_groups " 
	                                     + " WHERE uid = " + uid + "" 
	                                      + " AND gid = 2 ";
	                    
			 
	            // Send a query to DB
	            sendToServer(delsql2);
	            
	            //buy Photo
	            callBuyPhoto(false);
				
			}
			else
			{
				///are you sure
				int dialogButton=0;
				 dialogButton =  JOptionPane.showConfirmDialog (null,"The payment for the photo will be charged off your account","Confirm Payment", dialogButton);
				 JOptionPane.getRootFrame().setVisible(true);
				 
	            if(dialogButton == JOptionPane.YES_OPTION) 
	            {
	            		
					int location=photoDetails.getLocation();
					String timestamp=photoDetails.getTimeStamp();		
					
					
					String insertQuery2 = "adu"	+"INSERT INTO customer_photos "
     	                                        +"(uid,location,timestamp) VALUES "
                         	                   +"(" + uid + "," + location + ",'"+ timestamp +"'"+")";

                     // Send a query to DB
                     sendToServer(insertQuery2);
			
                   //update Query 
 					balance--;
 					  ///insert to customer_photos
 					String updateQuary = "adu"+ "UPDATE customer_account  " +
 	    										" SET balance =" + balance + "" + 
 	    										" WHERE uid = " + uid +""+" AND subscription_type = 2 ";
                     
 					// Send a query to DB
					sendToServer(updateQuary);
					
					 //view photo
					ViewPhoto();                  
	            }  
	            else if(dialogButton == JOptionPane.NO_OPTION) 
	            {
	            	
	            	JOptionPane.getRootFrame().setVisible(false);
	            }
	           
				
			}//flag-true-not expired
		}
		else
		{//not have account watch photo
			
		  //view photo or Sample	
			if (discount)
			{
				System.out.println("discount buy");
				//buy photo with discount;
				callBuyPhoto(true);
				 ViewSampleFlag=false;
				 change=false;
				 discount=false;
			}
			else
			 if (ViewSampleFlag)
			 {				
				ViewPhotoSample();
				 ViewSampleFlag=false;
				 change=false;
			 }
			 else
				 ViewPhoto();
			
		}
	}//Size-1
		
	}
	
	/**
	 * Inner class that handles when Buy Photo Pressed , implements ActionListener.
	 *
	 * @author Tal & Tomer
	 */
	class BuyPhotoListener extends AbstractListener
	{	
	 
		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			//create new instances of "buy photo" - gui / controller/ model 
			System.out.println("buy photo butto:"+e.getActionCommand());
			pressedPhotoButtonIndex = Integer.parseInt(e.getActionCommand());
			
		     int uid=up.getCurrUserID();
		    photoDetails = searchResModel.getPhotoHeadlineList().get(pressedPhotoButtonIndex);
				
				int location=photoDetails.getLocation();
				String timestamp=photoDetails.getTimeStamp();		
				
              	///send query if customer has package subscription or watch picture before and left 
			String sql = "search" + "SELECT a.balance,a.timestamp,NULL AS loc,NULL AS tamp " 
		                          + " FROM customer_account AS a " 
			                      + " WHERE a.uid = " + uid + ""+" AND a.subscription_type = 2 AND a.active=1"
			                      + " UNION "
			                      + "SELECT NULL,NULL,p.location, p.timestamp"
			                      + " FROM customer_photos AS p"
			                      + " WHERE p.uid="+ uid +" AND p.location="+location+" AND p.timestamp='"+ timestamp + "'";
			                      
			                    
					 
			// Send a query to DB
			sendToServer(sql);
			
		}
	}
	
	/**
	 * Inner class that handles when Buy Sample Pressed , implements ActionListener.
	 *
	 * @author Tal & Tomer
	 */

	class BuySampleListener extends AbstractListener
	{
		
		
		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			//create new instances of "buy photo sample" - gui / controller/ model  
			System.out.println("buy sample button :"+e.getActionCommand());
			
			pressedSampleButtonIndex = Integer.parseInt(e.getActionCommand());
			//change flag status-true
			ViewSampleFlag=true;
			change=true;
		     int uid=up.getCurrUserID();
			    photoDetails = searchResModel.getPhotoHeadlineList().get(pressedSampleButtonIndex);
					
					int location=photoDetails.getLocation();
					String timestamp=photoDetails.getTimeStamp();	 
					
		  	///send query watch Sample before and left 
					String sql = "search"   + "SELECT *"
					                      + " FROM customer_samples AS p"
					                      + " WHERE p.uid="+ uid +" AND p.locationsample="+location+" AND p.timestampsample='"+ timestamp + "'";
					                    
							 
					// Send a query to DB
					sendToServer(sql);
		}
	}
	
	/**
	 * Inner class that handles when View Photo Pressed , implements ActionListener.
	 *
	 * @author Tal & Tomer
	 */
	class ViewPhotoListener extends AbstractListener
	{
		
		/** The previus observer. */
		private Observer previusObserver;
		
		/**
		 * Instantiates a new view photo listener.
		 *
		 * @param previusObserver the previus observer
		 */
		public ViewPhotoListener(Observer previusObserver)
		{
			this.previusObserver = previusObserver;
		}
		
		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			//create new instances of "buy photo sample" - gui / controller/ model  
			System.out.println("view photo button : "+e.getActionCommand());
			int index=Integer.parseInt(e.getActionCommand());
			//set photo details
			SearchPhotoModel photoDetails = searchResModel.getPhotoHeadlineList().get(index);
			
	        //set the view photo model with a photo to display
			ArrayList<SearchPhotoModel> photosToDispley = new ArrayList<SearchPhotoModel>(); //set the photo list
			photosToDispley.add(photoDetails); //add a photo to list 
			SearchResultModel photos = new SearchResultModel(photosToDispley);
			ViewPhotoModel photoModel = new ViewPhotoModel(photos);
			
			//print the link to file (in console - for developer)
			String photoToDisplayFilePath = photoDetails.getLinkToFile();
			System.out.println("View Photo:"+photoToDisplayFilePath);
			
			//set the GUI and Controller of view photo
			ViewPhotoGUI photoView = new ViewPhotoGUI();
			ViewPhotoController viewPhotoCon = new ViewPhotoController(photoView,photoModel);
			
			//add observer to new controller and delete the rest
			setCurrentObserver(viewPhotoCon);						
			
			//add a listener to "back" button in View Photo  window
			setBackListener(previusObserver,photoView);
		}
	}
	
	
	/**
	 * Sets the action listeners.
	 */
	private void setActionListeners() 
	{
		listeners = new HashMap <String,AbstractListener>();
		listeners.put("Buy Photo",new BuyPhotoListener());
		listeners.put("View Photo",new ViewPhotoListener(this));
		listeners.put("Buy Sample",new BuySampleListener());
		
		String [] buttonNames =  searchResModel.getButtonNames();
		int nRows = searchResModel.getPhotoHeadlineList().size();
		
		for (int i = 0; i < nRows; i++) 
		{
			for (int j = 0; j < buttonNames.length; j++) 
			{
				searchResView.addButtonListener(listeners.get(buttonNames[j]), buttonNames[j], i);
			}
		}
	}
	
	

}
